#include "Hist.h"

Hist::Hist(CvSize size)
{
	rgb = cvCreateImage(size, 8, 3);
	r_plane = cvCreateImage(size, 8, 1);
	g_plane = cvCreateImage(size, 8, 1);
	b_plane = cvCreateImage(size, 8, 1);	
}

Hist::~Hist(void)
{
}

double Hist::computeBhattachayyaDistance(CvHistogram* histA, CvHistogram* histB)
{
	return cvCompareHist(histA, histB, CV_COMP_BHATTACHARYYA);
}

CvHistogram* Hist::computeCvHist(IplImage* image, CvRect rect)
{	
	initRGBImage(image);

	cvSetImageROI(r_plane, rect);
	cvSetImageROI(g_plane, rect);
	cvSetImageROI(b_plane, rect);	
	IplImage* planes[] = {r_plane, g_plane, b_plane};

	int bin_size = 8;
	CvHistogram* hist = NULL;
	{
		int hist_size[] = {bin_size, bin_size, bin_size};
		float r_plane[] = {0, 255};
		float g_plane[] = {0, 255};
		float b_plane[] = {0, 255};
		float* ranges[] = {r_plane, g_plane, b_plane};
		hist = cvCreateHist(3, hist_size, CV_HIST_ARRAY, ranges, 1);
	}
	cvCalcHist(planes, hist, 0, 0);
	cvNormalizeHist(hist, 1.0);
	cvResetImageROI(r_plane);
	cvResetImageROI(g_plane);
	cvResetImageROI(b_plane);

	return hist;
}

vector<float> Hist::computeHist(IplImage* image, CvRect rect)
{	
	initRGBImage(image);

	cvSetImageROI(r_plane, rect);
	cvSetImageROI(g_plane, rect);
	cvSetImageROI(b_plane, rect);		

	CvHistogram* histR = NULL;
	CvHistogram* histG = NULL;
	CvHistogram* histB = NULL;

	int hist_size = 8;
	float m_ranges[] = {0, 255};
	float* ranges[] = {m_ranges};
	histR = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
	histG = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);
	histB = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);

	cvCalcHist(&r_plane, histR, 0, 0);
	cvCalcHist(&g_plane, histG, 0, 0);
	cvCalcHist(&b_plane, histB, 0, 0);
	cvNormalizeHist(histR, 1.0);
	cvNormalizeHist(histG, 1.0);
	cvNormalizeHist(histB, 1.0);
	cvResetImageROI(r_plane);
	cvResetImageROI(g_plane);
	cvResetImageROI(b_plane);

	vector<float> mat = extractHist(histR, histG, histB);
	cvReleaseHist(&histR);
	cvReleaseHist(&histG);
	cvReleaseHist(&histB);
	return mat;
}

vector<float> Hist::extractHist(CvHistogram* histR, CvHistogram* histG, CvHistogram* histB)
{
	//CvMat* mat = cvCreateMat(1, 24, CV_32FC1);
	vector<float> vFeature;

	//int i = 0;
	float val;
	for (int b1 = 0; b1 < 8; b1++)
	{
		val = *cvGetHistValue_1D(histR, b1);
		vFeature.push_back(val);
		//*((float*)CV_MAT_ELEM_PTR( *mat, 0, i)) = val;
		//i++;
	}
	for (int b1 = 0; b1 < 8; b1++)
	{
		val = *cvGetHistValue_1D(histG, b1);
		vFeature.push_back(val);
	}
	for (int b1 = 0; b1 < 8; b1++)
	{
		val = *cvGetHistValue_1D(histB, b1);
		vFeature.push_back(val);
	}
	return vFeature;
}

void Hist::initRGBImage(IplImage* image)
{
	cvCvtColor(image, rgb, CV_BGR2RGB);	
	cvCvtPixToPlane(rgb, r_plane, g_plane, b_plane, 0);		
}